package com.xhsj.user.hr.system.service;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.xhsj.user.hr.system.entity.MenuTree;
import com.xhsj.user.hr.system.entity.TbGlobalMenu;
import com.xhsj.user.hr.system.mapper.TbGlobalMenuMapper;
import com.xhsj.user.hr.base.BaseService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xhsj.user.hr.system.query.GetListByParentIdQuery;
import com.xhsj.user.utils.Reflections;
import org.springframework.stereotype.Service;

import java.util.*;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.io.Serializable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

/**
 * <p>
 * 菜单权限表 服务实现类
 * </p>
 *
 * @author suxl
 * @since Aug 27, 2020 10:36:16 AM
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
//@CacheConfig(cacheNames = "TbGlobalMenu")
public class TbGlobalMenuService extends BaseService<TbGlobalMenuMapper, TbGlobalMenu> {
    @Autowired
    private TbGlobalMenuMapper dao;

    /**
     * 保存
     *
     * @author suxl
     * @date Aug 27, 2020 10:36:16 AM
     */
    @Override
    //@CacheEvict(cacheNames="TbGlobalMenu", allEntries=true)
    public boolean save(TbGlobalMenu entity) {

        Long parentId = entity.getParentId();
        if (parentId == 1) { // 顶级菜单
            entity.setParentIds("1");
        } else {
            String parentIds = dao.getParentIdsById(parentId);
            entity.setParentIds(parentIds + "," + parentId);
        }

        if (entity.getOrderNum() == null) {
            Integer orderNumber = dao.getMaxOrderNumberByParentId(parentId);
            entity.setOrderNum((orderNumber == null ? 0 : orderNumber) + 10);
        }
        return super.save(entity);
    }

    /**
     * 通过id获取数据
     *
     * @author suxl
     * @date Aug 27, 2020 10:36:16 AM
     */
    @Override
    //@Cacheable(key = "#id",sync = true)
    public TbGlobalMenu getById(Serializable id) {
        return dao.getById(id);
    }

    /**
     * 通过id删除数据
     *
     * @author suxl
     * @date Aug 27, 2020 10:36:16 AM
     */
    @Override
    //@CacheEvict(cacheNames="TbGlobalMenu", allEntries=true)
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

    /**
     * 批量删除数据
     *
     * @author suxl
     * @date Aug 27, 2020 10:36:16 AM
     */
    //@CacheEvict(cacheNames="SysDict", allEntries=true)
    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        return super.removeByIds(idList);
    }

    /**
     * 分页查询数据
     *
     * @author suxl
     * @date Aug 27, 2020 10:36:16 AM
     */
    //@Cacheable(key = "#data",sync = true)
    public IPage<TbGlobalMenu> selectPage(Map<String, Object> data) {
        int currentPage = 1;
        if (!Objects.isNull(data.get("page"))) {
            currentPage = (Integer) data.get("page");
        }
        int pageSize = 20;
        if (!Objects.isNull(data.get("size"))) {
            pageSize = (Integer) data.get("size");
        }

        TbGlobalMenu entity = JSON.parseObject(JSON.toJSONString(data), TbGlobalMenu.class);
        Page<TbGlobalMenu> page = new Page(currentPage, pageSize);
        QueryWrapper<TbGlobalMenu> wrapper = new QueryWrapper(entity);
        return super.selectPage(page, wrapper);
    }

    /**
     * 查询所有数据
     *
     * @author suxl
     * @date Aug 27, 2020 10:36:16 AM
     */
    @Override
    //@Cacheable(value = "TbGlobalMenu",sync = true)
    public List<TbGlobalMenu> selectAll() {
        return super.selectAll();
    }


    public Set<TbGlobalMenu> getPermissionByRoleIds(Set<Long> roleIds) {
        return dao.getPermissionByRoleIds(roleIds);
    }

    public Set<TbGlobalMenu> getMenuByRoleIds(Set<Long> roleIds) {
        return dao.getMenuByRoleIds(roleIds);
    }

    public void setSubChild(Object fa, Object sysMe) {
        if (fa instanceof List && sysMe instanceof List) {
            List<Object> father = (List<Object>) fa;
            List<Object> sysMenus = (List<Object>) sysMe;
            for (Object object : father) {
                List<Object> subChild = getSubChild(object, sysMenus);
                if (!CollectionUtils.isEmpty(subChild)) {
                    Reflections.setFieldValue(object, "children", subChild);
                    sysMenus.removeAll(subChild);
                    setSubChild(subChild, sysMenus);
                }
            }

        }

//        for (SysMenu sysMenu : father) {
//            List<SysMenu> subChild = getSubChild(sysMenu,sysMenus);
//            if (!CollectionUtils.isEmpty(subChild)){
//                sysMenu.setChildren(subChild);
//                sysMenus.removeAll(subChild);
//                setSubChild(subChild,sysMenus);
//            }
//        }
    }

    public List<Object> getSubChild(Object sysMenu, Object sysM) {
        List<Object> result = Lists.newArrayList();
        if (sysM instanceof List) {
            List<Object> sysMenus = (List<Object>) sysM;
            for (Object menu : sysMenus) {
                String id = String.valueOf(Reflections.getFieldValue(sysMenu, "id"));
                String parentId = String.valueOf(Reflections.getFieldValue(menu, "parentId"));
                if (id.equals(parentId)) {
                    result.add(menu);
                }
            }

            Collections.sort(result, new Comparator<Object>() {

                @Override
                public int compare(Object o1, Object o2) {
                    String sort = String.valueOf(Reflections.getFieldValue(o1, "orderNum"));
                    Integer sort1 = Integer.parseInt(String.valueOf(Reflections.getFieldValue(o1, "orderNum")));
                    Integer sort2 = Integer.parseInt(String.valueOf(Reflections.getFieldValue(o2, "orderNum")));
                    int i = sort1.compareTo(sort2);
                    return i;
                }
            });
        }

        return result;
    }

    /***
     * 查询菜单树
     * @author 苏小林
     * @date 2020/8/31 17:39
     * @return: java.util.List<com.xhsj.user.hr.system.entity.MenuTree>
     */
    public List<MenuTree> findMenuTree() {
        return dao.findMenuTree();
    }

    /**
     * 通过父id查询列表
     *
     * @author 苏小林
     * @date 2020/8/31 17:57
     * @param: getListByParentIdQuery
     * @return: java.util.List<com.xhsj.user.hr.system.entity.TbGlobalMenu>
     */
    public IPage<TbGlobalMenu> getListByParentId(GetListByParentIdQuery query) {
        Page<TbGlobalMenu> page = new Page(query.getPage(), query.getSize());
        return dao.getListByParentId(page, query.getParentId());
    }

    /**
     * 通过角色id查询菜单ids
     *
     * @author 苏小林
     * @date 2020/9/1 17:25
     * @param: id
     * @return: java.util.List<java.lang.Long>
     */
    public List<Long> getMenuIdsByRoleId(Long id) {
        return dao.getMenuIdsByRoleId(id);
    }

    /**
     * 处理菜单回显
     *
     * @author 苏小林
     * @date 2020/9/1 18:11
     * @param: list
     */
    public void handleEchoMenu(List<TbGlobalMenu> list, List<TbGlobalMenu> result1) {

        List<TbGlobalMenu> result = Lists.newArrayList();
        for (TbGlobalMenu tbGlobalMenu : list) {
            if (tbGlobalMenu.getChildren().size() > 0) {
//                handleEchoMenu(tbGlobalMenu.getChildren());
                result.addAll(tbGlobalMenu.getChildren());
            } else {
                result1.add(tbGlobalMenu);
            }
        }
        if (result.size() > 0) {
            handleEchoMenu(result, result1);
        }
    }

    /**
     * 删除菜单下所有数据
     *
     * @author 苏小林
     * @date 2020/9/3 13:11
     * @param: id
     */
    public void delById(Long id) {
        // 删除菜单及下面所有数据
        dao.delById(id);
    }

    /**
     * 查询所有菜单 包含权限
     *
     * @author 苏小林
     * @date 2020/9/18 11:54
     * @param: roleIds
     * @return: java.util.Set<com.xhsj.user.hr.system.entity.TbGlobalMenu>
     */
    public Set<TbGlobalMenu> getAllMenuByRoleIds(Set<Long> roleIds) {
        return dao.getAllMenuByRoleIds(roleIds);
    }

}
